package cn.xiaolang.function.network.io;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.LinkedList;
import java.util.concurrent.TimeUnit;

/**
 *
 * @author Dean
 * @date 2022-01-26
 */
public class SocketServerNIO {

    public static void main(String[] args) throws IOException, InterruptedException {
        ServerSocketChannel serverSocket = ServerSocketChannel.open();
        int port = 10010;
        serverSocket.bind(new InetSocketAddress(port));
        System.out.println("server up use port: " + port);
        // 重点：  OS  NON-BLOCKING
        serverSocket.configureBlocking(false);

        LinkedList<SocketChannel> clients = new LinkedList<>();
        while (true) {
            TimeUnit.MILLISECONDS.sleep(2000L);
            // 不会阻塞 返回 -1 和 null
            SocketChannel client = serverSocket.accept();
            if (null == client) {
                System.out.println("new connection waiting connected...");
            } else {
                client.configureBlocking(false);
                System.out.println(client.socket().getRemoteSocketAddress().toString() + " connected! ");
                clients.add(client);
            }
            // 堆里堆外
            ByteBuffer byteBuffer = ByteBuffer.allocateDirect(4096);

            for (SocketChannel c : clients) {
                // >0 -1 0 不会阻塞
                int read = c.read(byteBuffer);
                if (read > 0) {
                    byteBuffer.flip();
                    byte[] bytes = new byte[byteBuffer.limit()];
                    byteBuffer.get(bytes);
                    System.out.println("received data from client: " + c.socket().getRemoteSocketAddress().toString() + " ===> " + new String(bytes));
                    byteBuffer.clear();
                }
            }
        }
    }
}
